using Dapper;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement.H;
using RBAC.Interstructrue.Base;
using static RBAC.ErrorCode.APIEnums;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Data;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement
{
    /// <summary>
    /// 创建发货通知单处理器
    /// </summary>
    public class CreateDelivery_noticeHandler : IRequestHandler<CreateDelivery_noticeCommand, APIResult<int>>
    {
        private readonly IDbConnectionFactory _dbConnectionFactory;

        public CreateDelivery_noticeHandler(IDbConnectionFactory dbConnectionFactory)
        {
            _dbConnectionFactory = dbConnectionFactory;
        }

        public async Task<APIResult<int>> Handle(CreateDelivery_noticeCommand request, CancellationToken cancellationToken)
        {
            IDbConnection connection = null;
            IDbTransaction transaction = null;
            
            try
            {
                // 创建连接（连接工厂会自动打开连接）
                connection = _dbConnectionFactory.CreateConnection();
                
                // 开始事务
                transaction = connection.BeginTransaction();

                // 1. 自动生成单据编码
                var billCode = await GenerateBillCodeAsync(connection, transaction);

                // 2. 插入发货通知单主表
                var deliveryNoticeId = await InsertDeliveryNoticeAsync(connection, transaction, request, billCode);

                // 3. 插入发货通知单明细表
                await InsertDeliveryNoticeItemsAsync(connection, transaction, request.Items, deliveryNoticeId);

                // 4. 提交事务
                transaction.Commit();

                return new APIResult<int>
                {
                    Code = Success,
                    Msg = "发货通知单创建成功",
                    Data = deliveryNoticeId
                };
            }
            catch (Exception ex)
            {
                // 回滚事务
                if (transaction != null)
                {
                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception rollbackEx)
                    {
                        // 记录回滚异常，但不抛出
                        Console.WriteLine($"回滚事务失败: {rollbackEx.Message}");
                    }
                }
                
                return new APIResult<int>
                {
                    Code = Error,
                    Msg = $"创建发货通知单失败: {ex.Message}",
                    Data = 0
                };
            }
            finally
            {
                // 清理资源
                if (transaction != null)
                {
                    transaction.Dispose();
                }
                
                if (connection != null)
                {
                    connection.Dispose();
                }
            }
        }

        /// <summary>
        /// 自动生成单据编码
        /// </summary>
        private async Task<string> GenerateBillCodeAsync(IDbConnection connection, IDbTransaction transaction)
        {
            // 查询当前最大单据编码
            var sql = @"
                SELECT Bill_code 
                FROM Delivery_notice 
                WHERE Bill_code LIKE 'XSFH%' 
                ORDER BY Bill_code DESC 
                LIMIT 1";

            var lastBillCode = await connection.QueryFirstOrDefaultAsync<string>(sql, null, transaction);

            if (string.IsNullOrEmpty(lastBillCode))
            {
                // 如果没有记录，从XSFH000001开始
                return "XSFH000001";
            }

            // 提取数字部分并加1
            if (lastBillCode.Length >= 7 && int.TryParse(lastBillCode.Substring(4), out int currentNumber))
            {
                var nextNumber = currentNumber + 1;
                return $"XSFH{nextNumber:D6}";
            }

            // 如果解析失败，返回默认值
            return "XSFH000001";
        }

        /// <summary>
        /// 插入发货通知单主表
        /// </summary>
        private async Task<int> InsertDeliveryNoticeAsync(IDbConnection connection, IDbTransaction transaction, CreateDelivery_noticeCommand request, string billCode)
        {
            var sql = @"
                INSERT INTO Delivery_notice (
                    Bill_code, Bill_date, Status, Biz_type, Sales_order_code, 
                    Customer_id, Salesman_id, Warehouse_id, Receiver, Phone, 
                    Address, Delivery_date, Remark, Freight, Loading_fee,
                    CreateTime, CreateUser, IsDeleted
                ) VALUES (
                    @BillCode, @BillDate, @Status, @BizType, @SalesOrderCode,
                    @CustomerId, @SalesmanId, @WarehouseId, @Receiver, @Phone,
                    @Address, @DeliveryDate, @Remark, @Freight, @LoadingFee,
                    @CreateTime, @CreateUser, @IsDeleted
                );
                SELECT LAST_INSERT_ID();";

            var parameters = new
            {
                BillCode = billCode,
                BillDate = DateTime.Now,
                Status = 0, // 0 - 开立
                BizType = request.BizType,
                SalesOrderCode = request.SalesOrderCode,
                CustomerId = request.CustomerId,
                SalesmanId = request.SalesmanId,
                WarehouseId = request.WarehouseId,
                Receiver = request.Receiver,
                Phone = request.Phone,
                Address = request.Address,
                DeliveryDate = request.DeliveryDate,
                Remark = request.Remark,
                Freight = request.Freight,
                LoadingFee = request.LoadingFee,
                CreateTime = DateTime.Now,
                CreateUser = "当前登录人", // 这里应该从当前用户上下文获取
                IsDeleted = false
            };

            var result = await connection.ExecuteScalarAsync<long>(sql, parameters, transaction);
            return Convert.ToInt32(result);
        }

        /// <summary>
        /// 插入发货通知单明细表
        /// </summary>
        private async Task InsertDeliveryNoticeItemsAsync(IDbConnection connection, IDbTransaction transaction, System.Collections.Generic.List<CreateDelivery_noticeItemCommand> items, long deliveryNoticeId)
        {
            if (items == null || !items.Any())
                return;

            var sql = @"
                INSERT INTO Delivery_notice_item (
                    Delivery_notice_id, Material_id, Material_code, Material_name,
                    Unit, Qty, Package_qty, Batch_no, Remark,
                    CreateTime, CreateUser, IsDeleted
                ) VALUES (
                    @DeliveryNoticeId, @MaterialId, @MaterialCode, @MaterialName,
                    @Unit, @Qty, @PackageQty, @BatchNo, @Remark,
                    @CreateTime, @CreateUser, @IsDeleted
                )";

            foreach (var item in items)
            {
                var parameters = new
                {
                    DeliveryNoticeId = deliveryNoticeId,
                    MaterialId = item.MaterialId,
                    MaterialCode = item.MaterialCode,
                    MaterialName = item.MaterialName,
                    Unit = item.Unit,
                    Qty = item.Qty,
                    PackageQty = item.PackageQty,
                    BatchNo = item.BatchNo,
                    Remark = item.Remark,
                    CreateTime = DateTime.Now,
                    CreateUser = "当前登录人", // 这里应该从当前用户上下文获取
                    IsDeleted = false
                };

                await connection.ExecuteAsync(sql, parameters, transaction);
            }
        }
    }
} 